package ui;

import java.awt.Dimension;
import java.awt.Graphics;
import java.io.File;
import javax.swing.JInternalFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.WindowConstants;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import logica.DiccionarioDeVocabulario;
import logica.DiccionarioDeTag;
import java.util.Vector;

/**
 * Esta clase representa los documentos de texto.
 * Se utiliza en el desarrolo de la aplicación correspondiente al
 * Trabajo Práctico Nº 1 de Diseño e Implementación de Estructuras de Datos.
 * Universidad Tecnológica Nacional - Facultad Regional Santa Fe.
 * 
 * @author Cátedra DIED 2007.
 */
public class DocumentoDeTexto extends JInternalFrame implements KeyListener
{
	private static final long serialVersionUID = -7565056578582724727L;
// 	private File archivoDeTexto;
	private JTextArea areaDeTexto;
	private ScriptorPpal padre;
	private int id;
	private JScrollPane scrollPane;
    private JPopupMenu popup;
    private String cadenaInsertada;
    private DiccionarioDeVocabulario diccionario;
    private DiccionarioDeTag tags;

	/**
	 * Constructor.
	 * @param entrada Archivo de imagen.
	 * @param padre Ventana a la cual pertenece.
	 */
	public DocumentoDeTexto(File entrada, ScriptorPpal padre)
	{
		super(entrada.getName(),
					true,  //resizable
					true,  //closable
					true,  //maximizable
					true); //iconifiable

// 		archivoDeTexto = entrada;
		this.padre=padre;
		this.addInternalFrameListener(padre);
		this.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
        this.inicializar("");
        diccionario = null;
	}

	/**
	 * Constructor del documento de texto.
	 * @param nombre	Nombre del documento.
	 * @param padre		Ventana a la cual pertenece.
	 */
	public DocumentoDeTexto(String nombre, ScriptorPpal padre) {
		super(nombre,
					true,  //resizable
					true,  //closable
					true,  //maximizable
					true); //iconifiable

// 		archivoDeTexto = null;
		this.padre=padre;
		this.addInternalFrameListener(padre);
		this.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
	    this.inicializar("");
	}

	/**
	 * Inicializador de la ventana.
	 * @param imagenDeEntrada Imagen que contendrá la ventana.
	 */
	private void inicializar(String texto) {
	    // Se hace visible el Frame
	    this.setVisible( true );
	    this.setSize(200,200);
	    this.setPreferredSize(new Dimension(200,200));
	    this.areaDeTexto=new JTextArea();
	    this.areaDeTexto.setText(texto);
	    scrollPane = new JScrollPane();
        this.popup = new JPopupMenu();
	    scrollPane.getViewport().add(areaDeTexto);
	    this.getContentPane().add(scrollPane);
        //Agrega
        this.areaDeTexto.addKeyListener(this);
        this.cadenaInsertada= "";
	}
    
	/**
	 * Constructor.
	 * @param textoDeEntrada	Texto que contiene la ventana.
	 * @param titulo			Título de la ventana.
	 * @param padre				Ventana a la cual pertenece.
	 */
	public DocumentoDeTexto(String textoDeEntrada, String titulo, ScriptorPpal padre) {

		super(titulo,
					true,  //resizable
					true,  //closable
					true,  //maximizable
					true); //iconifiable

		this.padre=padre;
		this.addInternalFrameListener(padre);

// 		this.archivoDeTexto = null;
		this.areaDeTexto.setText(textoDeEntrada);

		this.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);

		if (textoDeEntrada==null)textoDeEntrada="";

	    this.inicializar(textoDeEntrada);
	}


    public void paint( Graphics g ) {
	    super.paint(g);
    }


	public ScriptorPpal getPadre() {
		return padre;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public void setTexto(String texto) {
		this.areaDeTexto.setText(texto);
	}

	public String getTexto() {
		if (this.areaDeTexto==null) return "";
		return this.areaDeTexto.getText();
	}

    public int getCursorPosition() {
        return this.areaDeTexto.getCaretPosition();
    }
    /**
     * Con este evento pretendo representar la localizacion de las palabras
     * encontradas mediante el comanod buscar, al ir presionando F3 ira
     * saltando y seleccionando una a una.
     */
    public void keyReleased(KeyEvent e) {
        if(e.getKeyCode() == KeyEvent.VK_F3 && padre.getProcesadorDeComandos().getSeleccion() != 0){
            System.out.println("Para ver las demas coincidencias presionar F3");
            if(padre.getProcesadorDeComandos().getSeleccionadas().size() > 
                    padre.getProcesadorDeComandos().getSeleccion()){
                int[] posiciones = (int[])padre.getProcesadorDeComandos().getSeleccionadas().elementAt(padre.getProcesadorDeComandos().getSeleccion());
                setSelect(posiciones[0], posiciones[1]);
                System.out.println(posiciones[0] + " " + posiciones[1] + " " + padre.getProcesadorDeComandos().getSeleccion());
                padre.getProcesadorDeComandos().aumentarSeleccion();
            }
       }
    }

    /**
     * Probando el funcionamiento de las teclas
     * Compruebo los valores ASCII de las teclas que me interesan a mi.Por lo
     * comprobado tanto las minusculas como las mayusculas tienen el mismo
     * valor ASCII, siendo que en http://www.asciitable.com/ no es asi.
     *
     */
    public void keyPressed(KeyEvent evt){
        int key = evt.getKeyCode();
        //System.out.println(key);
        if((key >= 65 && key <= 90) || (key >= 97 && key <= 122)){
            char tecla = evt.getKeyChar();
            this.cadenaInsertada+=tecla;
            //System.out.println("Presionaste: " + key + " que corresponde a: " + tecla);
            //Ver bien como hacer lo de la posicion.
            this.mostrarCoincidencias(this.getCursorPosition());
        }
        else if(key==10 || key==32 || key==9){
            this.cadenaInsertada="";
        }
    }
    /**
     * Desplegará el menu con las coincidencias en la posicion que le
     * corresponde.
     * @param pos Posicion actual del cursor.
     */
    public void mostrarCoincidencias(int pos){
        //System.out.println(this.cadenaInsertada);
        if(armarMenuPopup()){
            this.getContentPane().add(new JScrollPane(this.popup));
//             System.out.println("MANDO: "  + this.popup.getLocation());
            this.popup.show(areaDeTexto, pos + 10, pos + 5);
        }
    }

    /**
     * Formara la lista de coincidencias con las palabras que devulva la
     * consulta al diccionario.Primero borramos los items anteriores
     * @param pos Posicion actual del cursor
     */
    public boolean armarMenuPopup(){
        this.borrarItemPopup();
        if(cadenaInsertada.length() > 2 && diccionario != null){
            System.out.println(cadenaInsertada);
            Vector lista = diccionario.buscarCoincidencias(cadenaInsertada);
            // Espera a que el usuario seleccione una coincidencia, luego
            // modifica el texto y lo setea
            ActionListener action = new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    JMenuItem aux = (JMenuItem) e.getSource();
                    String texto = areaDeTexto.getText().replace(cadenaInsertada, aux.getText());
                    areaDeTexto.setText(texto);
                }
            };
            if(lista != null){
                for (int i=0; i < 5; i++){
                    JMenuItem aux = new JMenuItem((String)lista.elementAt(i));
                    aux.addActionListener(action);
                    this.popup.add(aux);
                }
                return true;
            }
        }
        return false;
    }
    /**
     * Borrara todas las coincidencias anteriores.
     * @param none
     */
    public void borrarItemPopup(){
            this.popup.removeAll();
    }

    public void cargarDiccionario(String path, boolean palabras){
        // carga el diccionario
        if(palabras){
            diccionario = new DiccionarioDeVocabulario(path);
            diccionario.cargarDiccionario();
        }
        else{
            tags = new DiccionarioDeTag(path);
            tags.cargarDiccionario();
        }
    }

    public boolean diccionarioCargado(){
        return (diccionario != null);
    }

    public void agregarPalabra(String palabra){
        diccionario.getRaiz().agregarPalabra(palabra);
    }

    public void borrarPalabra(String palabra){
        diccionario.getRaiz().borrarPalabra(palabra);
    }

    public void modificarPalabra(String palabraVieja, String palabraNueva){
        diccionario.getRaiz().modificarPalabra(palabraVieja, palabraNueva);
    }


   /**
    * @see java.awt.event.KeyListener#keyTyped(java.awt.event.KeyEvent)
    */
    public void keyTyped(KeyEvent e) {
        if(e.getKeyChar()==KeyEvent.VK_ESCAPE){
            System.out.println("Presiono tecla escape");
            this.padre.getPanelDeComando().getLineaDeComandos().requestFocus();
        }
    }

    public JTextArea getAreaDeTexto(){
        return this.areaDeTexto;
    }
    /**
     * Utilizada para seleccionar el texto en el JTextArea
     * @param start     Posicion inicial de la cadena.
     * @param end       Posicion final de la cadena.
     */
    public void setSelect(int start, int end){
        areaDeTexto.select(start, end);
    }

}
